package com.flyox.game.militarychess.client.view;

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

import com.flyox.game.militarychess.CONSTS;
import com.flyox.game.militarychess.bean.ChessDesk;
import com.flyox.game.militarychess.bean.ChessSeat;
import com.flyox.game.militarychess.bean.ChessDesk.DESK_STATE;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_NAME;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_STATE;
import com.flyox.game.militarychess.client.services.DataService;
import com.flyox.game.militarychess.client.view.composite.ButtonFilter;
import com.flyox.game.militarychess.client.view.composite.HrefButtonArea;
import com.flyox.game.militarychess.message.ChessPackage;
import com.flyox.game.militarychess.message.Request;
import com.flyox.game.militarychess.util.Secret;
import com.flyox.game.militarychess.util.SerialUtil;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class HallDeskPanel extends javax.swing.JPanel implements MouseListener, MouseMotionListener {

	private static final long serialVersionUID = -9110726387310455765L;
	private final static long UPDATERATE = 100;
	ChessFrame chessFrame;
	ChessDesk dsk = null;
	BufferedImage baseEmptyDeskImage;
	BufferedImage header1Image;
	HrefButtonArea areas[];
	public static final int BRIGHTER = 0;
	public static final int DARKER = 1;
	int hlmode = BRIGHTER;
	public int hlpercent = 50;

	MediaTracker tracker;
	DataService dataService = new DataService();

	public void refresh(ChessDesk cd) {
		Graphics2D g2d = (Graphics2D) baseEmptyDeskImage.getGraphics();
		if (dsk.isPlaying()) {
			g2d.drawImage(chessFrame.busyImage, 0, 0, this);
		} else {
			g2d.drawImage(chessFrame.emptyImage, 0, 0, this);
		}
		initBaseImg();
		initAreas(areas);
		this.repaint();
	}

	private void initBaseImg() {
		Graphics2D g = (Graphics2D) baseEmptyDeskImage.getGraphics();
		AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
		g.setComposite(alpha);
		Hashtable<SEAT_NAME, ChessSeat> seats = dsk.getSeats();
		if (!seats.get(SEAT_NAME.S1).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 60, 10, this);
		}
		if (!seats.get(SEAT_NAME.S2).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 110, 10, this);
		}
		if (!seats.get(SEAT_NAME.S3).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 160, 10, this);
		}
		if (!seats.get(SEAT_NAME.S4).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 210, 10, this);
		}
		if (!seats.get(SEAT_NAME.S5).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 60, 100, this);
		}
		if (!seats.get(SEAT_NAME.S6).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 110, 100, this);
		}
		if (!seats.get(SEAT_NAME.S7).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 160, 100, this);
		}
		if (!seats.get(SEAT_NAME.S8).getSeatState().equals(SEAT_STATE.EMPTY)) {
			g.drawImage(header1Image, 210, 100, this);
		}
		try {
			OutputStream out = new FileOutputStream("c:\\myImage.jpg");
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(baseEmptyDeskImage);
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ImageFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		g.dispose();
	}

	private void initAreas(HrefButtonArea[] as) {
		if (as.length == 8) {
			as[0] = new HrefButtonArea(SEAT_NAME.S1);
			as[0].init(this, 60, 10, 40, 35);
			as[1] = new HrefButtonArea(SEAT_NAME.S2);
			as[1].init(this, 110, 10, 40, 35);
			as[2] = new HrefButtonArea(SEAT_NAME.S3);
			as[2].init(this, 160, 10, 40, 35);
			as[3] = new HrefButtonArea(SEAT_NAME.S4);
			as[3].init(this, 210, 10, 40, 35);
			as[4] = new HrefButtonArea(SEAT_NAME.S5);
			as[4].init(this, 60, 100, 40, 35);
			as[5] = new HrefButtonArea(SEAT_NAME.S6);
			as[5].init(this, 110, 100, 40, 35);
			as[6] = new HrefButtonArea(SEAT_NAME.S7);
			as[6].init(this, 160, 100, 40, 35);
			as[7] = new HrefButtonArea(SEAT_NAME.S8);
			as[7].init(this, 210, 100, 40, 35);
		}
	}

	public HallDeskPanel(ChessFrame chessFrame, ChessDesk desk) {
		super();
		this.chessFrame = chessFrame;
		this.dsk = desk;
		initGUI();
	}

	private void initGUI() {
		tracker = new MediaTracker(this);
		// default image
		try {
			baseEmptyDeskImage = ImageIO.read(this.getClass().getResource("/com/flyox/game/militarychess/client/res/img/empty_desk.png"));
			header1Image = ImageIO.read(this.getClass().getResource("/com/flyox/game/militarychess/client/res/img/head-1.png"));
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		initBaseImg();

		areas = new HrefButtonArea[8];
		initAreas(areas);
		checkSize();
		addMouseListener(this);
		addMouseMotionListener(this);
		setPreferredSize(new Dimension(baseEmptyDeskImage.getWidth(this), baseEmptyDeskImage.getHeight(this)));
	}

	public Image getHighlight(int x, int y, int w, int h) {
		return getHighlight(x, y, w, h, hlmode, hlpercent);
	}

	Image getHighlight(int x, int y, int w, int h, int mode, int percent) {
		return getHighlight(x, y, w, h, new ButtonFilter(false, hlpercent, 5, w, h));
	}

	public Image getHighlight(int x, int y, int w, int h, ImageFilter filter) {
		ImageFilter cropfilter = new CropImageFilter(x, y, w, h);
		ImageProducer prod = new FilteredImageSource(baseEmptyDeskImage.getSource(), cropfilter);
		return makeImage(prod, filter, 0);
	}

	Image makeImage(Image orig, ImageFilter filter) {
		return makeImage(orig.getSource(), filter);
	}

	Image makeImage(ImageProducer prod, ImageFilter filter) {
		return makeImage(prod, filter, (prod == baseEmptyDeskImage.getSource()) ? 1 : 0);
	}

	Image makeImage(ImageProducer prod, ImageFilter filter, int ID) {
		Image filtered = createImage(new FilteredImageSource(prod, filter));
		tracker.addImage(filtered, ID);
		return filtered;
	}

	void addImage(Image img) {
		tracker.addImage(img, 1);
	}

	public void destroy() {
		removeMouseListener(this);
		removeMouseMotionListener(this);
	}

	void checkSize() {
		int w = baseEmptyDeskImage.getWidth(this);
		int h = baseEmptyDeskImage.getHeight(this);
		if (w > 0 && h > 0) {
			repaint(0, 0, w, h);
		}
	}

	public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
		if ((infoflags & (WIDTH | HEIGHT)) != 0) {
			checkSize();
		}
		if ((infoflags & (SOMEBITS | FRAMEBITS | ALLBITS)) != 0) {
			repaint(((infoflags & (FRAMEBITS | ALLBITS)) != 0) ? 0 : UPDATERATE, x, y, width, height);
		}
		return (infoflags & (ALLBITS | ERROR)) == 0;
	}

	public void paint(Graphics g) {
		g.drawImage(baseEmptyDeskImage, 0, 0, this);
		if (areas != null) {
			for (int i = areas.length; --i >= 0;) {
				areas[i].highlight(g);
			}
		}
	}

	public void update(Graphics g) {
		paint(g);
	}

	int pressX;
	int pressY;

	public void mouseClicked(MouseEvent e) {
		for (int i = 0; i < areas.length; i++) {
			if (areas[i].inside(pressX, pressY)) {
				if (areas[i].lift(e.getX(), e.getY())) {
					int deskNum = dsk.getDeskNum();
					SEAT_NAME seatName = areas[i].getSeatName();
					DESK_STATE ds = dsk.getDeskStates();
					// send requst
					if (ds != DESK_STATE.PLAYING && dsk.getSeats().get(seatName).getSeatState().equals(SEAT_STATE.EMPTY)) {
						ChessPackage cp = new ChessPackage(CONSTS.CMD_SEC, dataService.getPlayerID());
						Request request = new Request();
						request.setCommand(CONSTS.CMD_SEC_ONSEAT);
						request.setDeskNum(dsk.getDeskNum());
						request.setSeatName(seatName);
						byte[] serRequest = null;
						try {
							serRequest = SerialUtil.enSerial(request);
						} catch (IOException e1) {
							e1.printStackTrace();
							return;
						}
						serRequest = Secret.encryptMsg(serRequest, dataService.getPlayer().getDesKey());
						cp.setContent(serRequest);

						// 临时保存 状态
						dataService.getPlayer().setDeskNum(deskNum);
						dataService.getPlayer().setSeatName(seatName);
						// 发送请求
						chessFrame.control.sendRequest(cp);
					} else {
						JOptionPane.showMessageDialog(this, "不能坐下", "错误提示", JOptionPane.INFORMATION_MESSAGE, null);
						System.out.println("busy seat! " + ds);
					}
					break;
				}
			}
		}
		e.consume();

	}

	public void mousePressed(MouseEvent e) {
		pressX = e.getX();
		pressY = e.getY();
		for (int i = 0; i < areas.length; i++) {
			if (areas[i].inside(pressX, pressY)) {
				if (areas[i].press(pressX, pressY)) {
					// do other
					// System.out.println("inside mousePressed");
					break;
				}
			}
		}
		e.consume();
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
		for (int i = 0; i < areas.length; i++) {
			areas[i].checkExit();
		}
		e.consume();
	}

	public void mouseDragged(MouseEvent e) {
		mouseMoved(e);
		for (int i = 0; i < areas.length; i++) {
			if (areas[i].inside(pressX, pressY)) {
				if (areas[i].drag(e.getX(), e.getY())) {
					//
					break;
				}
			}
		}
		e.consume();
	}

	public void mouseMoved(MouseEvent e) {
		boolean eaten = false;
		for (int i = 0; i < areas.length; i++) {
			if (!eaten && areas[i].inside(e.getX(), e.getY())) {
				eaten = areas[i].checkEnter(e.getX(), e.getY());
			} else {
				areas[i].checkExit();
			}
		}
		e.consume();
	}
}
